﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using Autodesk.Revit.DB;
using Gpc;
using YJKArch.Utils;

namespace YJKAreaCutter.Utils.ClipPolygon
{
	public class ClipPolygonUtils
	{
		public static bool ClipPolygon(List<MyPolygon> lstPolygon, MyPolygon ConvertPolygon, AreaClip clipType = AreaClip.SuperSet)
		{
			bool result = false;
			try
			{
				if (ClipPolygonUtils.m_Polygon == null)
				{
					ClipPolygonUtils.m_Polygon = ClipPolygonUtils.CreateUnionPolygon(lstPolygon);
				}
				Polygon polygon = ClipPolygonUtils.ConstructGpcPolygon(ConvertPolygon);
				switch (clipType)
				{
				case AreaClip.Separation:
					if (ClipPolygonUtils.m_Polygon.ClipPolygon(polygon, ClipOp.Int).ToGraphicsPath(ContourType.All, GraphicsPathType.Polygons).PointCount < 1)
					{
						result = true;
					}
					break;
				case AreaClip.Intersection:
					if (ClipPolygonUtils.m_Polygon.ClipPolygon(polygon, ClipOp.Int).ToGraphicsPath(ContourType.All, GraphicsPathType.Polygons).PointCount > 1)
					{
						result = true;
					}
					break;
				case AreaClip.SuperSet:
				{
					GraphicsPath graphicsPath = polygon.ClipPolygon(ClipPolygonUtils.m_Polygon, ClipOp.Diff).ToGraphicsPath(ContourType.All, GraphicsPathType.Polygons);
					if (graphicsPath.PointCount == 0)
					{
						result = true;
					}
					break;
				}
				case AreaClip.SubSet:
				{
					GraphicsPath graphicsPath2 = ClipPolygonUtils.m_Polygon.ClipPolygon(polygon, ClipOp.Diff).ToGraphicsPath(ContourType.All, GraphicsPathType.Polygons);
					if (graphicsPath2.PointCount == 0)
					{
						result = true;
					}
					break;
				}
				case AreaClip.Equal:
					if (polygon.ClipPolygon(ClipPolygonUtils.m_Polygon, ClipOp.Xor).ToGraphicsPath(ContourType.All, GraphicsPathType.Polygons).PointCount < 1)
					{
						result = true;
					}
					break;
				}
			}
			catch
			{
			}
			return result;
		}

		public static void DisposeRecordPolygon()
		{
			if (ClipPolygonUtils.m_Polygon != null)
			{
				ClipPolygonUtils.m_Polygon.Dispose();
				ClipPolygonUtils.m_Polygon = null;
			}
		}

		public static Polygon CreateUnionPolygon(List<MyPolygon> lstRegion)
		{
			Polygon polygon = null;
			new List<PointF>();
			int num = 0;
			foreach (MyPolygon polygon2 in lstRegion)
			{
				if (num == 0)
				{
					polygon = ClipPolygonUtils.ConstructGpcPolygon(polygon2);
					num++;
				}
				else if (polygon != null)
				{
					Polygon clipPolygon = ClipPolygonUtils.ConstructGpcPolygon(polygon2);
					PointF[] pathPoints = polygon.ClipPolygon(clipPolygon, ClipOp.Union).ToGraphicsPath(ContourType.All, GraphicsPathType.Polygons).PathPoints;
					if (pathPoints.Length > 2)
					{
						Polygon polygon3 = new Polygon();
						polygon3.AddContour(pathPoints, false);
						if (polygon != null)
						{
							polygon.Dispose();
							polygon = null;
						}
						polygon = polygon3;
					}
				}
			}
			return polygon;
		}

		private static Polygon ConstructGpcPolygon(MyPolygon polygon)
		{
			Polygon polygon2 = new Polygon();
			List<PointF> list = new List<PointF>();
			List<Curve> boundary = polygon.Boundary;
			if (boundary.Count > 0)
			{
				foreach (Curve curve in boundary)
				{
					IList<XYZ> list2 = curve.Tessellate();
					for (int i = 1; i < list2.Count; i++)
					{
						list.Add(new PointF((float)list2[i].X, (float)list2[i].Y));
					}
				}
				if (list.Count > 2)
				{
					PointF[] contour = list.ToArray();
					polygon2.AddContour(contour, false);
				}
				return polygon2;
			}
			return null;
		}

		private static double CalculateArea(PointF[] points)
		{
			List<double> list = new List<double>();
			List<double> list2 = new List<double>();
			foreach (PointF pointF in points)
			{
				list.Add((double)pointF.X);
				list2.Add((double)pointF.Y);
			}
			return Geometry.AoArea(list.Count, list.ToArray(), list2.ToArray());
		}

		private static Polygon m_Polygon;
	}
}
